package com.skyline.common.validation;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.Form;
import org.apache.commons.validator.FormSet;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorResources;

import com.skyline.common.util.SpringUtils;

/**
 * 生成校验脚本（实际生产中需要配置classpath来运行）
 * 
 * @author wuqh
 * */
public class ValidationJsGenerator {
	private static final Log LOGGER = LogFactory.getLog(ValidationJsGenerator.class);
	public static final ValidatorResources validatorResources = SpringUtils.getBean(
			ValidationFactory.class).getValidatorResources();

	@SuppressWarnings("unchecked")
	public static String generateValidationJs(String formName) {
		StringBuilder totleJs = new StringBuilder("(function($){$().ready(function() {\n");
		StringBuilder rulesJs = new StringBuilder("rules:{\n");
		StringBuilder messagesJs = new StringBuilder("messages:{\n");
		Form form = validatorResources.getForm(Locale.getDefault(), formName);

		int fieldIndex = 0;
		List<Field> fields = form.getFields();
		for (Field field : fields) {
			if (fieldIndex != 0) {
				rulesJs.append(",\n");
				messagesJs.append(",\n");
			}
			rulesJs.append(field.getProperty()).append(":{");
			messagesJs.append(field.getProperty()).append(":{");

			int dependencyIndex = 0;
			List<String> dependencyList = field.getDependencyList();
			for (String dependency : dependencyList) {
				if (dependencyIndex != 0) {
					rulesJs.append(',');
					messagesJs.append(',');
				}
				ValidatorAction va = validatorResources.getValidatorAction(dependency);
				String message = ValidationUtils.getMessage(va, field);

				if (dependency.equals("required")) {
					rulesJs.append("required:true");
					messagesJs.append("required:'").append(message).append('\'');
				}

				if (dependency.equals("minlength")) {
					try {
						int min = Integer.parseInt(field.getVarValue("minlength"));
						rulesJs.append("minlength:").append(min);
						messagesJs.append("minlength:'").append(message).append('\'');
					} catch (Exception e) {
						LOGGER.info("生成" + form.getName() + "的" + field.getProperty()
								+ "字段的minlength校验失败", e);
					}

				}

				if (dependency.equals("maxlength")) {
					try {
						int max = Integer.parseInt(field.getVarValue("maxlength"));
						rulesJs.append("maxlength:").append(max);
						messagesJs.append("maxlength:'").append(message).append('\'');
					} catch (Exception e) {
						LOGGER.info("生成" + form.getName() + "的" + field.getProperty()
								+ "字段的minlength校验失败", e);
					}
				}

				if (dependency.equals("mask")) {
					String mask = field.getVarValue("mask");
					rulesJs.append("regexmatch:").append('/').append(mask).append('/');
					messagesJs.append("regexmatch:'").append(message).append('\'');
				}

				if (dependency.equals("byte") || dependency.equals("short")
						|| dependency.equals("integer") || dependency.equals("long")
						|| dependency.equals("double") || dependency.equals("float")) {
					// FIXME:全部归为数值型，实际应用中是否需要区分
					rulesJs.append("number:true");
					messagesJs.append("number:'").append(message).append('\'');
				}

				if (dependency.equals("date")) {
					// FIXME:使用正则，不再使用日期类型
				}

				if (dependency.toLowerCase().endsWith("range")) {
					try {
						int min = Integer.parseInt(field.getVarValue("min"));
						int max = Integer.parseInt(field.getVarValue("max"));
						rulesJs.append("range:").append('[').append(min).append('\'').append(max)
								.append(']');
						messagesJs.append("range:'").append(message).append('\'');
					} catch (Exception e) {
						LOGGER.info("生成" + form.getName() + "的" + field.getProperty() + "字段的"
								+ dependency + "校验失败", e);
					}
				}

				// if (dependency.endsWith("email")) {
				// // FIXME:使用正则，不再使用邮件类型
				// }

				if (dependency.endsWith("notEqualTo")) {
					try {
						String toId = field.getVarValue("toid");
						rulesJs.append("notEqualTo:").append("\"#").append(formName)
								.append(" [name='").append(toId).append("']\"");
						messagesJs.append("notEqualTo:'").append(message).append('\'');
					} catch (Exception e) {
						LOGGER.info("生成" + form.getName() + "的" + field.getProperty()
								+ "字段的notEqualTo校验失败", e);
					}
				}

				if (dependency.endsWith("equalTo")) {
					try {
						String toId = field.getVarValue("toid");
						rulesJs.append("equalTo:").append("\"#").append(formName)
								.append(" [name='").append(toId).append("']\"");
						messagesJs.append("equalTo:'").append(message).append('\'');
					} catch (Exception e) {
						LOGGER.info("生成" + form.getName() + "的" + field.getProperty()
								+ "字段的notEqualTo校验失败", e);
					}
				}

				// if (dependency.endsWith("submitToken")) {
				// //FIXME:表单防重复提交校验不生成JS
				// }
				dependencyIndex++;
			}
			rulesJs.append('}');
			messagesJs.append('}');
			fieldIndex++;
		}
		rulesJs.append("\n},\n");
		messagesJs.append("\n}\n");
		totleJs.append("$(\"#" + formName + "\").validate({\n").append(rulesJs.toString())
				.append(messagesJs.toString()).append("});\n});\n})(jQuery);");
		try {
			return new String(totleJs.toString().getBytes("utf-8"));
		} catch (UnsupportedEncodingException e) {
			LOGGER.info("脚本编码转换失败！使用未编码转换的字符串。");
			return totleJs.toString();
		}
	}

	@SuppressWarnings("unchecked")
	public static void generateValidationJsFile(String basePath) throws IOException {
		FormSet formSet = null;
		try {
			java.lang.reflect.Field field = validatorResources.getClass().getDeclaredField(
					"defaultFormSet");
			field.setAccessible(true);
			formSet = (FormSet) field.get(validatorResources);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (formSet != null) {
			Set<String> formNames = formSet.getForms().keySet();
			for (String formName : formNames) {
				File file = new File(basePath, formName + ".js");
				String js = generateValidationJs(formName);
				FileUtils.writeStringToFile(file, js);
			}

		}
	}

	public static void main(String... strings) throws IOException {
		generateValidationJsFile("/home/skyline/WorkSpace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/skyline/js/validator/");
		System.out.println("成功生成js文件");
	}
}
